﻿using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;

namespace Xmlt.ViewEngine
{
    internal class ProcessedXmlHelper
    {
        public static XmlReader CreateProcessedXmlStream(Stream input, XmlResolver resolver)
        {
            if (!input.CanSeek)
            {
                byte[] buffer = new byte[4 * 1024];

                MemoryStream stream = new MemoryStream();
                int offset = 0;
                int read = input.Read(buffer, 0, buffer.Length);
                while (read != 0)
                {
                    stream.Write(buffer, 0, read);
                    offset += read;
                    read = input.Read(buffer, 0, buffer.Length);
                }
                stream.SetLength(stream.Position);
                stream.Position = 0;
                input = stream;
            }
            var settings = new XmlReaderSettings { ProhibitDtd = false, ValidationType = ValidationType.None, CloseInput = true, XmlResolver = resolver };

            using (XmlReader reader = XmlReader.Create(input, settings))
            {
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        input.Position = 0;
                        return XmlReader.Create(input, settings);
                    }
                    else if (reader.NodeType == XmlNodeType.ProcessingInstruction && reader.Name == "xml-stylesheet")
                    {
                        string s = reader.Value;
                        int i = s.IndexOf("href=\"") + 6;
                        s = s.Substring(i, s.IndexOf('\"', i) - i);

                        Uri uri = resolver.ResolveUri(null, s);

                        XslCompiledTransform transform = XsltTransformCache.Get(uri.Scheme == "file" ? uri.LocalPath : uri.ToString());

                        // TODO: Add resources resolved by XmlVirtualPathResolver to the cache dependencies
                        if (transform == null)
                        {

                            using (var transformReader = XmlReader.Create(uri.ToString(), settings))
                            {
                                transform = new XslCompiledTransform();
                                transform.Load(transformReader, new XsltSettings { EnableDocumentFunction = true, EnableScript = true }, resolver);
                            }
                            //XsltTransformCache.Set(uri.Scheme == "file" ? uri.LocalPath : uri.ToString(), transform, virtualPathProvider.GetCacheDependency(path, new[] { path }, DateTime.Now));
                        }
                        MemoryStream output = new MemoryStream();
                        XsltArgumentList args = new XsltArgumentList();
                        args.XsltMessageEncountered += new XsltMessageEncounteredEventHandler((x, a) =>
                        {
                            string message = a.Message;
                        });
                        input.Position = 0;
                        using (XmlReader reader2 = XmlReader.Create(input, settings))
                        {
                            using (XmlWriter writer = XmlWriter.Create(output, new XmlWriterSettings { CloseOutput = false }))
                            {
                                transform.Transform(reader2, args, writer, resolver);
                                output.Flush();
                                output.SetLength(output.Position);
                                output.Position = 0;
                                StreamReader sr = new StreamReader(output);
                                string ss = sr.ReadToEnd();
                                output.Position = 0;
                            }
                        }
                        settings.CloseInput = false;
                        return XmlReader.Create(output, settings);
                        //XslTransformer.Load(XmlReader.Create(output, settings), new XsltSettings { EnableDocumentFunction = true, EnableScript = true }, new XmlVirtualPathResolver(System.Web.HttpContext.Current.Request.Url.ToString()));
                        //XsltTransformCache.Set(viewPath, XslTransformer, virtualPathProvider.GetCacheDependency(viewPath, new[] { viewPath, path }, DateTime.Now));

                    }
                }
            }
            return XmlReader.Create(input, settings);
        }
    }

}
